package com.bestcem.xm.common.core.uitls;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import com.google.protobuf.Timestamp;
import com.google.protobuf.util.Timestamps;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Date;
import java.util.Objects;
import java.util.TimeZone;

/**
 * 时间工具类
 *
 * @author XiaoYunSong <ys.xiao@idiaoyan.cn>
 * @version v1.0
 * @date 2021/6/29 11:30
 */
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class GrpcDateUtil {

    /**
     * UTC
     */
    public static final String UTC = "UTC";

    /**
     * UTC 时区
     */
    public static final ZoneOffset UTC_ZONE = ZoneOffset.of("+0");
    /**
     * Beijing 时区
     */
    public static final ZoneOffset BEIJING_ZONE = ZoneOffset.of("+8");
    /**
     * UTC 时区
     */
    public static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone(ZoneId.ofOffset(UTC, UTC_ZONE));

    /**
     * Beijing 时区
     */
    public static final TimeZone BEIJING_TIME_ZONE = TimeZone.getTimeZone(ZoneId.ofOffset(UTC, BEIJING_ZONE));

    /**
     * java 时间格式化字符串统一格式
     */
    public static final String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

    /**
     * yyyy-MM-dd格式
     */
    public static final String YYYY_MM_DD = "yyyy-MM-dd";

    /**
     * yyyy/MM/dd格式
     */
    public static final String YYYYMMDD = "yyyy/MM/dd";

    /**
     * protobuf 输入时间转 java 时间统一时区 | 北京时间
     */
    public static final ZoneOffset INPUT_ZONE = BEIJING_ZONE;
    /**
     * java 时间转 protobuf 输出时间统一时区 | 北京时间
     */
    public static final ZoneOffset OUTPUT_ZONE = BEIJING_ZONE;
    /**
     * java 时间存入 MongoDB 时间统一时区 | UTC
     */
    public static final ZoneOffset INSERT_ZONE = UTC_ZONE;
    /**
     * MongoDB 时间取出为 java 时间统一时区 | UTC
     */
    public static final ZoneOffset SELECT_ZONE = UTC_ZONE;

    /**
     * 联系人导出文件日期格式
     */
    public static final String MEMBER_EXPORT_FORMAT = "yyyy/MM/dd HH:mm:ss";

    /**
     * 联系人excel文件日期格式
     */
    public static final String MEMBER_EXCEL_DATE_FORMAT = "yyyy/M/d";

    /**
     * java 时间格式化生成工单编号专用
     */
    public static final String DATETIME_PATTERN_FORTICKETNO = "yyyyMMdd";

    /**
     * 接口数据源中的只显示时分的格式
     */
    public static final String DATETIME_PATTERN_EXTERNAL_REFRESH_TIME = "HH:mm";

    /**
     * 飞书专用格式
     */
    public static final String DATETIME_PATTERN_FEISHU = "yyyy/MM/dd HH:mm";

    /**
     * 前端交互日期格式
     */
    public static final String OUT_DATETIME_PATTERN = "yyyy/MM/dd HH:mm:ss";

    /**
     * 前端交互日期格式
     */
    public static final String OUT_DATE_PATTERN = "yyyyMMdd";

    /**
     * 格式化时间戳
     */
    public static String simpleFormatTimestamp(Long timestamp) {
        if (Objects.isNull(timestamp)) {
            return "";
        }
        DateTime date = cn.hutool.core.date.DateUtil.date(timestamp);
        return cn.hutool.core.date.DateUtil.format(date, DatePattern.NORM_DATETIME_PATTERN);
    }

    /**
     * java.util.Date 转换成 protobuf.Timestamp
     *
     * @param date Date
     * @return A Timestamp from the number of milliseconds elapsed from the epoch.
     * @author XiaoYunSong <ys.xiao@idiaoyan.cn>
     * @date 2021/6/29 11:30
     */
    public static Timestamp getTimestamp(Date date) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), BEIJING_ZONE);
        return getTimestamp(localDateTime);
    }

    /**
     * java.time.LocalDateTime 转换成 protobuf.Timestamp
     *
     * @param localDateTime LocalDateTime
     * @return A Timestamp from the number of milliseconds elapsed from the epoch.
     * @author XiaoYunSong <ys.xiao@idiaoyan.cn>
     * @date 2021/6/29 11:30
     */
    public static Timestamp getTimestamp(LocalDateTime localDateTime) {
        Instant instant = localDateTime.toInstant(OUTPUT_ZONE);
        return Timestamps.fromMillis(instant.toEpochMilli());
    }

    /**
     * protobuf.Timestamp 转换成 java.time.LocalDateTime
     *
     * @param timestamp protobuf.timestamp
     * @return LocalDateTime
     * @author XiaoYunSong <ys.xiao@idiaoyan.cn>
     * @date 2021/6/29 11:30
     **/
    public static LocalDateTime getLocalDateTime(Timestamp timestamp) {
        return Instant.ofEpochMilli(Timestamps.toMillis(timestamp)).atZone(INPUT_ZONE).toLocalDateTime();
    }

    /**
     * protobuf.Timestamp 转换成 java.util.Date
     *
     * @param timestamp protobuf.timestamp
     * @return LocalDateTime
     * @author XiaoYunSong <ys.xiao@idiaoyan.cn>
     * @date 2021/6/29 11:30
     **/
    public static Date getDate(Timestamp timestamp) {
        LocalDateTime localDateTime = getLocalDateTime(timestamp);
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }
}
